package basic;

/**
 * @Description: TODO 克隆
 * @Author: wzj
 * @Date: 2020/6/11 9:59
 */
/*
Demo中Student中person没有克隆，所以是浅克隆，克隆后的s1的person和s0的person是同一个地址
Actor的person也克隆了，是深克隆，克隆后的a1的person和a0的person不是同一个地址
 */
public class CloneDemo {
    public static void main(String[] args) {
        try {
            Person person=new Person("人");
            Person person1=new Person("人1");
            Student s0=new Student(person,"男",20);
            System.out.println("****************************************  浅克隆  ****************************************");
            System.out.println("****************************************  前  ****************************************");
            System.out.println("s0地址： "+s0.toString());
            System.out.println("s0 person地址： "+s0.getPerson().toString());
            System.out.println("s0： "+s0.toString1());
            System.out.println("****************************************  后  ****************************************");
            Student s1=(Student) s0.clone();
            System.out.println("s1地址： "+s1.toString());
            System.out.println("s1 person地址： "+s1.getPerson().toString());
            System.out.println("s1： "+s1.toString1());
            System.out.println("****************************************  修改s1后  ****************************************");
            s1.setSex("女");
            s1.setAge(30);
            s1.setPerson(person1);
            System.out.println("s0地址： "+s0.toString());
            System.out.println("s0 person地址： "+s0.getPerson().toString());
            System.out.println("s0： "+s0.toString1());
            System.out.println("s1地址： "+s1.toString());
            System.out.println("s1 person地址： "+s1.getPerson().toString());
            System.out.println("s1： "+s1.toString1());

            System.out.println("\n\n\n\n");

            Actor a0=new Actor(person,"男",20);
            System.out.println("****************************************  深克隆  ****************************************");
            System.out.println("****************************************  前  ****************************************");
            System.out.println("a0地址： "+a0.toString());
            System.out.println("a0 person地址： "+a0.getPerson().toString());
            System.out.println("a0： "+a0.toString1());
            System.out.println("****************************************  后  ****************************************");
            Actor a1=(Actor) a0.clone();
            System.out.println("a1地址： "+a1.toString());
            System.out.println("a1 person地址： "+a1.getPerson().toString());
            System.out.println("a1： "+a1.toString1());
            System.out.println("****************************************  修改s1后  ****************************************");
            a1.setSex("女");
            a1.setAge(30);
            a1.setPerson(person1);
            System.out.println("a0地址： "+a0.toString());
            System.out.println("a0 person地址： "+a0.getPerson().toString());
            System.out.println("a0： "+a0.toString1());
            System.out.println("a1地址： "+a1.toString());
            System.out.println("a1 person地址： "+a1.getPerson().toString());
            System.out.println("a1： "+a1.toString1());
            System.out.println("\n\n\n\n");

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

class Person implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String toString1() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Student implements Cloneable{
    private Person person;
    private String sex;
    private int age;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString1() {
        return "Student{" +
                " sex='" + sex + '\'' +
                ", age=" + age +
                '}'+person.toString1();
    }

    public Student(Person person, String sex, int age) {
        this.person = person;
        this.sex = sex;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//只有对象本身进行了clone，引用的对象没有克隆，是浅克隆
    }
}

class Actor implements Cloneable{
    private Person person;
    private String sex;
    private int age;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString1() {
        return "Actor{" +
                " sex='" + sex + '\'' +
                ", age=" + age +
                '}'+person.toString1();
    }

    public Actor(Person person, String sex, int age) {
        this.person = person;
        this.sex = sex;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Actor actor=(Actor)super.clone();
        if(person!=null){//引用的对象也进行克隆
            actor.person=(Person)person.clone();
        }
        return actor;
    }
}